<script setup>
import { getRolePage, addRole, updateRole, deleteRole, updateRoleStatus, getPermissionPage, addRolePermission, deleteRolePermission } from '@/api/auth'
import { getDateTimeStr } from '@/utils/formatDate'
import { uniqueArray, compareArrays } from '@/utils/arrutils'
// 每页展示数据条目
const PAGE_SIZE = 10
// 分页查询参数
const rolePageMsg = ref({
  pageNum: 1,
  pageSize: PAGE_SIZE,
  roleCode: null,
  roleDesc: null,
  roleName: null,
  createTimeStartAndEnd: [new Date(2024, 0, 1), new Date(2025, 0, 1)],
  status: null
})
// 分页查询结果
const rolePageList = ref([])
// 分页查询条目总数
const rolePageTotal = ref(0)
// 表格行选择器
const rowSelection = ref({
  type: 'checkbox',
  showCheckedAll: true,
  onlyCurrent: false,
})

// 权限列表
const permissionList = ref([])
// 进入页面后进行一次查询展示
onMounted(async () => {
  const tempRes = await getPermissionPage({
    pageNum: 1, pageSize: 99, status: 1
  })
  permissionList.value = tempRes.list
  await getTableData()
})

// 展示的表格数据
const tableData = ref([])
// 把查询结果映射到表格
const resMsgToTableData = () => {
  tableData.value = []
  for (let i = 0; i < rolePageList.value.length; i++) {
    const tempObj = {
      key: rolePageList.value[i].id,
      tableIndex: i + 1 + PAGE_SIZE * (rolePageMsg.value.pageNum - 1),
      roleCode: rolePageList.value[i].roleCode,
      roleName: rolePageList.value[i].roleName,
      roleDesc: rolePageList.value[i].roleDesc,
      createTime: getDateTimeStr(rolePageList.value[i].createTime),
      status: rolePageList.value[i].status,
      permissionList: rolePageList.value[i].permissionList.map(item => item.permissionCode),
      oldPermissionList: rolePageList.value[i].permissionList.map(item => item.permissionCode),
      permissionAllList: uniqueArray([...rolePageList.value[i].permissionList, ...permissionList.value], 'permissionCode').map(item => ({ value: item.permissionCode, label: item.permissionName }))
    }
    tableData.value.push(tempObj)
  }
}

// 修改页码
const pageChange = async (pageNum) => {
  rolePageMsg.value.pageNum = pageNum
  getTableData()
}

// 查询
const getTableData = async () => {
  const tempRes = await getRolePage(rolePageMsg.value)
  rolePageList.value = tempRes.list
  rolePageTotal.value = +tempRes.total
  resMsgToTableData()
}
// 新增角色对话框可见状态
const addRoleVisible = ref(false)
// 新增角色对话框表单数据
const addRoleForm = ref({
  roleCode: "",
  roleDesc: "",
  roleName: ""
})
// 新增角色表单元素
const addRoleFormDom = ref()
// 对新增角色数据进行校验和赋值
const addRoleBeforeOk = async () => {
  let isPass = true
  await addRoleFormDom.value.validate().then(res => {
    if (res) {
      isPass = false
    }
  })
  return isPass
}
// 提交新增角色表单数据
const addRoleOk = async () => {
  await addRole(addRoleForm.value)
  addRoleFormDom.value.resetFields()
  addRoleFormDom.value.clearValidate()
  await getTableData()
}
// 取消新增
const addRoleCancel = () => {
  addRoleFormDom.value.resetFields()
  addRoleFormDom.value.clearValidate()
}

// 修改角色对话框可见状态
const updateRoleVisible = ref(false)
// 修改角色对话框表单数据
const updateRoleForm = ref({
  // 下面是需要提交的数据
  id: 0,
  roleCode: "",
  roleDesc: "",
  roleName: "",
  status: 1,
  // 下面是初始数据，用于判断是否修改
  oldRoleCode: "",
  oldRoleDesc: "",
  oldRoleName: "",
})
// 修改角色表单元素
const updateRoleFormDom = ref()
// 弹出修改角色对话框
const updateRoleModal = (data) => {
  updateRoleForm.value.id = data.key
  updateRoleForm.value.roleCode = `${data.roleCode}`
  updateRoleForm.value.roleDesc = data.roleDesc
  updateRoleForm.value.roleName = data.roleName
  updateRoleForm.value.oldRoleCode = `${data.roleCode}`
  updateRoleForm.value.oldRoleDesc = data.roleDesc
  updateRoleForm.value.oldRoleName = data.roleName
  updateRoleVisible.value = true
}
// 对修改角色数据进行校验和赋值
const updateRoleBeforeOk = async () => {
  let isPass = true
  await updateRoleFormDom.value.validate().then(res => {
    if (res) {
      isPass = false
    }
  })
  return isPass
}
// 提交修改角色表单数据
const updateRoleOk = async () => {
  await updateRole(updateRoleForm.value)
  updateRoleFormDom.value.resetFields()
  updateRoleFormDom.value.clearValidate()
  await getTableData()
}
// 取消修改
const updateRoleCancel = () => {
  updateRoleFormDom.value.resetFields()
  updateRoleFormDom.value.clearValidate()
}

// 开关修改状态
const switchChange = async (data) => {
  await updateRoleStatus({
    id: data.key,
    status: data.status ? 0 : 1
  })
  data.status = data.status ? 0 : 1
}

// 删除角色对话框可见状态
const deleteRoleVisible = ref(false)

// 弹出删除角色对话框
const deleteRoleModal = (data) => {
  deleteRoleIds.value.push(data.key)
  deleteRoleVisible.value = true
}
// 删除角色的ids
const deleteRoleIds = ref([])
// 多选框选中的ids
const selectedRoleIds = ref([])
// 批量删除
const deleteRoleBatch = () => {
  deleteRoleIds.value = selectedRoleIds.value
  deleteRoleVisible.value = true
}
// 提交删除角色
const deleteRoleOk = async () => {
  await deleteRole(deleteRoleIds.value)
  deleteRoleIds.value = []
  await getTableData()
}

// 修改角色拥有的权限
const updateRolePermission = async (record) => {
  const tempItemObj = compareArrays(record.permissionList, record.oldPermissionList)
  record.oldPermissionList = record.permissionList
  if (tempItemObj.key) {
    await addRolePermission({
      roleCode: record.roleCode,
      permissionCode: tempItemObj.item
    })
  } else {
    await deleteRolePermission({
      roleCode: record.roleCode,
      permissionCode: tempItemObj.item
    })
  }
}
</script>

<template>
  <!-- 新增角色对话框 start -->
  <a-modal v-model:visible="addRoleVisible" @ok="addRoleOk" :on-before-ok="addRoleBeforeOk"
    @cancel="addRoleCancel" title="新增角色">
    <a-form :model="addRoleForm" ref="addRoleFormDom">
      <a-form-item field="roleCode" label="角色编码" :rules="[{required:true,message:'角色编码不能为空'}]">
        <a-input v-model="addRoleForm.roleCode" placeholder="请输入角色编码" type="number" />
      </a-form-item>
      <a-form-item field="roleDesc" label="角色描述" :rules="[{required:true,message:'角色描述不能为空'}]">
        <a-input v-model="addRoleForm.roleDesc" placeholder="请输入角色描述" />
      </a-form-item>
      <a-form-item field="roleName" label="角色名称" :rules="[{required:true,message:'角色名称不能为空'}]">
        <a-input v-model="addRoleForm.roleName" placeholder="请输入角色名称" />
      </a-form-item>
    </a-form>
  </a-modal>
  <!-- 新增角色对话框 end -->
  <!-- 修改角色对话框 start -->
  <a-modal v-model:visible="updateRoleVisible" @ok="updateRoleOk" :on-before-ok="updateRoleBeforeOk"
    @cancel="updateRoleCancel" title="修改角色">
    <a-form :model="updateRoleForm" ref="updateRoleFormDom">
      <a-form-item field="roleCode" label="角色编码" :rules="[{required:true,message:'角色编码不能为空'}]">
        <a-input v-model="updateRoleForm.roleCode" placeholder="请输入角色编码" type="number" />
      </a-form-item>
      <a-form-item field="roleDesc" label="角色描述" :rules="[{required:true,message:'角色描述不能为空'}]">
        <a-input v-model="updateRoleForm.roleDesc" placeholder="请输入角色描述" />
      </a-form-item>
      <a-form-item field="roleName" label="角色名称" :rules="[{required:true,message:'角色名称不能为空'}]">
        <a-input v-model="updateRoleForm.roleName" placeholder="请输入角色名称" />
      </a-form-item>
    </a-form>
  </a-modal>
  <!-- 修改角色对话框 end -->
  <!-- 删除角色对话框 start -->
  <a-modal v-model:visible="deleteRoleVisible" @ok="deleteRoleOk" @cancel="deleteRoleIds=[]"
    title="删除角色">
    <div>你确定要删除该角色吗</div>
  </a-modal>
  <!-- 删除角色对话框 end -->
  <a-layout class="layout-demo">
    <a-layout-header>
      <!-- 查询参数输入区 start -->
      <div class="box">
        <span class="my-span">角色编码</span>
        <a-input placeholder="请输入角色编码" allow-clear class="my-input"
          v-model="rolePageMsg.roleCode" />
      </div>
      <div class="box">
        <span class="my-span">角色名称</span>
        <a-input placeholder="请输入角色名称" allow-clear class="my-input"
          v-model="rolePageMsg.roleName" />
      </div>
      <div class="box">
        <span class="my-span">角色描述</span>
        <a-input placeholder="请输入角色描述" allow-clear class="my-input"
          v-model="rolePageMsg.roleDesc" />
      </div>
      <div class="box">
        <span class="my-span">创建时间</span>
        <a-range-picker class="my-input"
          style="width: 248px; border: 1px solid rgb(217, 217, 217); box-sizing: border-box;"
          v-model="rolePageMsg.createTimeStartAndEnd" :value-format="'Date'" />
      </div>
      <div class="box">
        <a-button class="my-btn" type="outline" @click="getTableData">查询</a-button>
      </div>
      <div class="box">
        <a-button class="my-btn" type="outline"
          @click="addRoleVisible=!addRoleVisible">新增</a-button>
      </div>
      <!-- 查询参数输入区 end -->
    </a-layout-header>
    <a-layout-content>
      <!-- 信息展示表格 start -->
      <a-table :data="tableData" class="my-table" :pagination="false" :row-selection="rowSelection"
        v-model:selectedKeys="selectedRoleIds">
        <template #columns>
          <a-table-column :align="'center'" title="序号" data-index="tableIndex" />
          <a-table-column :align="'center'" title="角色编码" data-index="roleCode" />
          <a-table-column :align="'center'" title="角色名称" data-index="roleName" />
          <a-table-column :align="'center'" title="角色描述" data-index="roleDesc" />
          <a-table-column :align="'center'" title="创建日期" data-index="createTime" />
          <a-table-column :align="'center'" title="拥有的权限">
            <template #cell="record">
              <div>
                <a-select placeholder="无权限" multiple :max-tag-count="2" :style="{width: 'auto'}"
                  v-model="record.record.permissionList"
                  @change="updateRolePermission(record.record)">
                  <a-option v-for="item in record.record.permissionAllList" :key="item.value"
                    :value="item.value" :label="item.label" />
                </a-select>
              </div>
            </template>
          </a-table-column>
          <!-- 状态开关，0是停用，1是启用-->
          <a-table-column :align="'center'" title="状态">
            <template #cell="record">
              <a-switch :checked-value="1" :unchecked-value="0"
                :default-checked="record.record.status ? true : false"
                @change="switchChange(record.record)" :checked-text="'启用'" :unchecked-text="'停用'" />
            </template>
          </a-table-column>
          <!-- 修改操作和删除操作 -->
          <a-table-column :align="'center'" title="操作">
            <template #cell=record>
              <a-button type="outline" @click="updateRoleModal(record.record)"
                style="margin-right:20px">修改</a-button>
              <a-button type="outline" @click="deleteRoleModal(record.record)">删除</a-button>
            </template>
          </a-table-column>
        </template>
      </a-table>
      <!-- 信息展示表格 end -->
      <!-- 批量删除和分页器 -->
      <div>
        <a-button class="table-end-btn" type="outline" @click="deleteRoleBatch">批量删除</a-button>
        <a-pagination class="table-end-pagination" :total="rolePageTotal" :page-size="PAGE_SIZE"
          @change="pageChange" />
      </div>
    </a-layout-content>
    <a-layout-footer>Footer</a-layout-footer>
  </a-layout>
</template>

<style scoped>
.layout-demo :deep(.arco-layout-header) {
  height: auto;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
  font-size: 16px;
  font-stretch: condensed;
  text-align: center;
}

.layout-demo :deep(.arco-layout-header) .box {
  display: inline-block;
  margin: 12px 0;
}

.my-btn {
  margin-left: 12px;
}

.layout-demo :deep(.arco-layout-sider) {
  width: 206px;
}

.table-head-div {
  margin-top: 40px;
}

.my-table {
  margin: 64px 64px 0;
}

.table-end-btn,
.table-end-pagination {
  margin: 12px 64px;
}

.table-end-btn {
  float: left;
}

.table-end-pagination {
  float: right;
}

.my-span {
  margin: 0 12px;
}

.my-input {
  width: 128px;
  border: 1px solid #d9d9d9;
}

.tag:nth-child(n + 2) {
  margin-left: 8px;
}
</style>